/**
 * 产品模式下的webpack配置
 *
 * 注意。两种模式的配置有较大差异！！
 */
const path = require('path');
const webpack = require('webpack');

const HtmlWebpackPlugin = require('html-webpack-plugin');
const pxtorem = require('postcss-pxtorem');
const webConfig = require('./webs-config'); //项目配置
const fs = require('fs-extra'); //文件操作库
//所有的资源路径
let addressList=[];

//根据不同的路径返回唯一的数字编码用于添加到class后缀
let getClassIndex=function(address){
    if(addressList.indexOf(address)>-1){
        return addressList.indexOf(address)
    }
    else{
        addressList.push(address);
        return addressList.indexOf(address);
    }
};

//自定义插件
const getNowFormatDate = require('./plugin/w-getNowFormatDate'); //当前时间插件
const WScriptPlugin = require('./plugin/w-script-plugin'); //自定义JS属性插件

const outputPath = path.join(__dirname, 'src', 'webs', webConfig.name + webConfig.startPath, webConfig.outputPath || 'dist');
fs.remove(outputPath); //删除之前打包输出的文件夹


// webpack中生成HTML的插件，

module.exports = {
    entry: {
        // 文件入口配置
        index: './src/webs/' + webConfig.name + webConfig.startPath + '/js/index',
        vendor: [
            'react-router',
            'react-redux',
            'redux',
            'antd-mobile'
        ]
        // 为了优化，切割代码，提取第三方库（实际上，我们将会引入很多第三方库）
    },
    // 页面入口文件配置

    output: {
        // 文件输出配置

        path: outputPath,
        // 输出目录的配置，模板、样式、脚本、图片等资源的路径配置都相对于它.

        publicPath: webConfig.publicPath || '',
        // 模板、样式、脚本、图片等资源对应的server上的路径

        filename: 'bundle-' + getNowFormatDate() + '.js',
        // 命名生成的JS

        chunkFilename: '[name]-' + getNowFormatDate() + '.js', //'[name].[chunkhash:5].chunk.js'
        //按需加载js区块
    },


    externals: {
        //使用外链引入以下JS文件
        'react': 'React',
        'react-dom': 'ReactDOM'
    },

    plugins: [
        new webpack.optimize.OccurrenceOrderPlugin(),
        // webapck 会给编译好的代码片段一个id用来区分
        // 而这个插件会让webpack在id分配上优化并保持一致性。
        // 具体是的优化是：webpack就能够比对id的使用频率和分布来得出最短的id分配给使用频率高的模块

        new webpack.optimize.UglifyJsPlugin({
            // 最紧凑的输出
            beautify: false,
            // 删除所有的注释
            comments: false,
            compress: {
                // 在UglifyJs删除没有用到的代码时不输出警告
                warnings: false,
                // 删除所有的 `console` 语句
                // 还可以兼容ie浏览器
                drop_console: true,
                // 内嵌定义了但是只用到一次的变量
                collapse_vars: true,
                // 提取出出现多次但是没有定义成变量去引用的静态值
                reduce_vars: true,
            }
        }),

        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production'),
            __DEV__: false
        }),

        new webpack.LoaderOptionsPlugin({
            minimize: true,
            options: {
                postcss: () => [require('precss'),
                    require('autoprefixer'),
                    require('rucksack-css'),
                    pxtorem({
                        rootValue: 100,
                        propWhiteList: [],
                    })
                ]
            }
        }),
        // 很多库的内部，有process.NODE_ENV的判断语句，
        // 改为production。最直观的就是没有所有的debug相关的东西，体积会减少很多

        new webpack.optimize.CommonsChunkPlugin({name: 'vendor', filename: 'vendor.bundle.js'}),
        // 'vendor' 就是把依赖库(比如react react-router, redux)全部打包到 vendor.js中
        // 'vendor.js' 就是把自己写的相关js打包到bundle.js中
        // 一般依赖库放到前面，所以vendor放第一个

        new HtmlWebpackPlugin({
            template: 'src/webs/' + webConfig.name + webConfig.startPath + '/index.html',
            // html模板的路径

            title: webConfig.title,

            filename: 'index.html',
            // 文件名以及文件将要存放的位置

            favicon: './src/favicon.ico',
            // favicon路径

            inject: 'body',
            // js插入的位置，true/'head'  false/'body'

            chunks: ['vendor', 'index'],
            // 指定引入的chunk，根据entry的key配置，不配置就会引入所有页面的资源

            hash: false,
            // 这样每次客户端页面就会根据这个hash来判断页面是否有必要刷新
            // 在项目后续过程中，经常需要做些改动更新什么的，一但有改动，客户端页面就会自动更新！

            minify: {
                // 压缩HTML文件
                removeComments: true,
                // 移除HTML中的注释

                collapseWhitespace: true,
                // 删除空白符与换行符
            }
        }),

        new WScriptPlugin({})
    ],

    resolve: {
        // 实际就是自动添加后缀，默认是当成js文件来查找路径
        modules: ["node_modules"],
        extensions: ['.web.js', '.js', '.json'],

        // 路径别名, 懒癌福音
        alias: {
            app: path.resolve(__dirname, 'src/js'),
            // 以前你可能这样引用 import { Nav } from '../../components'
            // 现在你可以这样引用 import { Nav } from 'app/components'

            style: path.resolve(__dirname, 'src/styles')
            // 以前你可能这样引用 import "../../../styles/mixins.scss"
            // 现在你可以这样引用 import "style/mixins.scss"

            // 注意：别名只能在.js文件中使用。
        }
    },

    module: {
        loaders: [
            {
                test: /\.js$/,
                use: ['babel-loader'],
                exclude: /node_modules/
            },
            {
                test: /\.scss$/,
                include: path.resolve(__dirname, 'src/js'),
                // 组件样式，需要私有化，单独配置
                use: [
                    {loader: 'style-loader'},
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true,
                            importLoaders: 1,
                            getLocalIdent: (context, localIdentName, localName, options) => {
                                return localName + '_' + getClassIndex(context.resourcePath);
                            }
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            parser: 'postcss-scss'
                        }
                    }
                ]
            },
            // 组件样式，需要私有化，单独配置

            {
                test: /\.scss$/,
                include: path.resolve(__dirname, 'src/styles'),
                use: [
                    {loader: 'style-loader'},
                    {loader: 'css-loader'},
                    {
                        loader: 'postcss-loader',
                        options: {
                            parser: 'postcss-scss'
                        }
                    }
                ]
            },
            // 公有样式，不需要私有化，单独配置

            {
                test: /\.scss$/,
                include: path.resolve(__dirname, 'src/webs/' + webConfig.name + webConfig.startPath + '/js'),
                // 组件样式，需要私有化，单独配置
                use: [
                    {loader: 'style-loader'},
                    {
                        loader: 'css-loader',
                        options: {
                            modules: true,
                            importLoaders: 1,
                            getLocalIdent: (context, localIdentName, localName, options) => {
                                return localName + '_' + getClassIndex(context.resourcePath);
                            }
                        }
                    },
                    {
                        loader: 'postcss-loader',
                        options: {
                            parser: 'postcss-scss'
                        }
                    }
                ]
            },
            // 项目组件样式，需要私有化，单独配置

            {
                test: /\.scss$/,
                include: path.resolve(__dirname, 'src/webs/' + webConfig.name + webConfig.startPath + '/styles'),
                use: [
                    {loader: 'style-loader'},
                    {loader: 'css-loader'},
                    {
                        loader: 'postcss-loader',
                        options: {
                            parser: 'postcss-scss'
                        }
                    }
                ]
            },
            // 项目公有样式，不需要私有化，单独配置

            {
                test: /\.css$/,
                include: path.resolve(__dirname, 'node_modules'),
                use: [
                    'style-loader',
                    'css-loader',
                    'postcss-loader'
                ]
            },

            {
                test: /\.(otf|eot|svg|ttf|woff|woff2).*$/,
                loader: 'url-loader',
                options: {
                    limit: 10000
                }
            },
            {
                test: /\.(gif|jpe?g|png|ico)$/,
                loader: 'url-loader',
                options: {
                    limit: 10000
                }
            }
        ]
    }
};
